#include "forgetdialog.h"
#include <QAction>
#include <QCryptographicHash>
#include <QJsonDocument>
#include <QRegularExpression>
#include "QUrl"
#include "global.h"
#include "httpmanager.h"
#include "ui_forgetdialog.h"
ForgetDialog::ForgetDialog(QWidget *parent, unsigned short counter)
    : QDialog(parent)
    , ui(new Ui::ForgetDialog)
    , _counter(counter)
{
    ui->setupUi(this);
    ui->err_tip->clear();
    ui->forget_edt_password->setEchoMode(QLineEdit::Password);
    QAction *passwd_action = new QAction(ui->forget_edt_password);
    passwd_action->setIcon(QIcon(":/icon/icon/unvisible.png"));
    ui->forget_edt_password->addAction(passwd_action, QLineEdit::TrailingPosition);
    connect(passwd_action, &QAction::triggered, this, [this, passwd_action](bool checked) {
        if (ui->forget_edt_password->echoMode() == QLineEdit::Password) {
            ui->forget_edt_password->setEchoMode(QLineEdit::Normal);
            passwd_action->setIcon(QIcon(":/icon/icon/visible.png"));
        } else {
            ui->forget_edt_password->setEchoMode(QLineEdit::Password);
            passwd_action->setIcon(QIcon(":/icon/icon/unvisible.png"));
        }
    });
    connect(ui->forget_edt_user, &QLineEdit::editingFinished, this, &ForgetDialog::CheckUserValid);
    connect(ui->forget_edt_email, &QLineEdit::editingFinished, this, &ForgetDialog::CheckEmailValid);
    connect(ui->forget_edt_verify, &QLineEdit::editingFinished, this, &ForgetDialog::CheckVerifyValid);
    connect(ui->forget_edt_password, &QLineEdit::editingFinished, this, &ForgetDialog::CheckPassWordValid);
    // 请求完成，处理请求
    connect(HttpManager::GetInstance().get(),
            &HttpManager::sig_reset_mod_finish,
            this,
            &ForgetDialog::slot_reset_mod_finish);
    _timer.stop();
    // 限制获取验证码按钮counter秒内不能再次获取
    connect(&_timer, &QTimer::timeout, this, [counter, this]() {
        try {
            if (--_counter == 0) {
                _timer.stop();
                _counter = counter;
                ui->btn_verify->setText("获取");
                ui->btn_verify->setEnabled(true);
                return;
            }
            ui->btn_verify->setText(QString("%1").arg(_counter));
            return;
        } catch (std::exception const &e) {
            qDebug() << e.what();
        }
    });
    // 注册相关请求处理函数
    initHttpHandlers();
}

ForgetDialog::~ForgetDialog()
{
    qDebug() << "ForgetDialog析构\n";
    delete ui;
}

bool ForgetDialog::CheckUserValid()
{
    if (ui->forget_edt_user->text().isEmpty()) {
        AddTipErr(TipErr::TIP_USER_ERR, tr("用户名不能为空"));
        ui->btn_verify->setEnabled(false);
        return false;
    }
    DelTipErr(TipErr::TIP_USER_ERR);
    ui->btn_verify->setEnabled(true);
    return true;
}

bool ForgetDialog::CheckEmailValid()
{
    //验证邮箱格式
    QString email = ui->forget_edt_email->text();
    QRegularExpression regex(R"(^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$)");
    bool match = regex.match(email).hasMatch();
    if (!match) {
        AddTipErr(TipErr::TIP_EMAIL_ERR, tr("邮箱地址不正确"));
        ui->btn_verify->setEnabled(false);
        return false;
    }
    DelTipErr(TipErr::TIP_EMAIL_ERR);
    ui->btn_verify->setEnabled(true);
    return true;
}

bool ForgetDialog::CheckPassWordValid()
{
    QString pass = ui->forget_edt_password->text();
    if (pass.length() < 6 || pass.length() > 15) {
        AddTipErr(TipErr::TIP_PWD_ERR, tr("密码长度应为6-15"));
        return false;
    }
    // 创建一个正则表达式
    QRegularExpression regExp("^[a-zA-Z0-9!@#$%^&*]{6,15}$");
    bool match = regExp.match(pass).hasMatch();
    if (!match) {
        AddTipErr(TipErr::TIP_PWD_ERR, tr("不能包含非法字符串"));
        return false;
    }
    DelTipErr(TipErr::TIP_PWD_ERR);
    return true;
}

bool ForgetDialog::CheckVerifyValid()
{
    QString verify = ui->forget_edt_verify->text();
    if (verify.isEmpty()) {
        AddTipErr(TipErr::TIP_VERIFY_ERR, tr("验证码不能为空"));
        return false;
    } else if (verify.length() != 4) {
        AddTipErr(TipErr::TIP_VERIFY_ERR, tr("验证码长度必须为4"));
        return false;
    } else {
        DelTipErr(TipErr::TIP_VERIFY_ERR);
        return true;
    }
}

void ForgetDialog::AddTipErr(TipErr te, QString tips)
{
    _tip_errs[te] = tips;
    showTip(tips);
}

void ForgetDialog::DelTipErr(TipErr te)
{
    _tip_errs.remove(te);
    if (_tip_errs.isEmpty()) {
        ui->err_tip->clear();
        return;
    } else {
        showTip(_tip_errs.begin().value());
    }
}

void ForgetDialog::showTip(const QString &err_str, bool success)
{
    ui->err_tip->setText(err_str);
    if (success) {
        ui->err_tip->setProperty("state", "normal");
    } else {
        ui->err_tip->setProperty("state", "error");
    }
    repolish(ui->err_tip);
}

// 获取验证码
void ForgetDialog::on_btn_verify_clicked()
{
    //获取用户名和邮箱
    QString email = ui->forget_edt_email->text();
    if (email.isEmpty()) {
        showTip("邮箱不能为空");
        return;
    }
    QJsonObject root;
    root["email"] = email;
    // 发送获取验证码请求
    HttpManager::GetInstance()->PostHttpReq(QUrl(gate_url_prefix + "/get_verifycode"),
                                            root,
                                            ReqId::ID_GET_VARIFY_CODE,
                                            Modules::RESETPWDMOD);
    _timer.start(1000);
    ui->btn_verify->setEnabled(false);
    ui->btn_verify->setText(QString("15"));
}

void ForgetDialog::slot_reset_mod_finish(ReqId id, QString res, ErrorCode ec)
{
    if (ec != ErrorCode::SUCCESS) {
        showTip("网路请求错误！");
        return;
    }
    // 解析Json字符串
    QJsonDocument jsonDoc = QJsonDocument::fromJson(res.toUtf8());
    if (jsonDoc.isNull()) {
        showTip("Json 解析失败");
        return;
    }
    // json 解析错误
    if (!jsonDoc.isObject()) {
        showTip("json解析失败");
        return;
    }
    // 调用回调函数
    _handlers[id](jsonDoc.object());
}

void ForgetDialog::initHttpHandlers()
{
    // 验证码处理请求
    _handlers.insert(ReqId::ID_GET_VARIFY_CODE, [this](const QJsonObject &jsonObject) {
        int error = jsonObject["error"].toInt();
        if (error != ErrorCode::SUCCESS) {
            showTip("参数错误");
            return;
        }
        auto email = jsonObject["email"].toString();
        showTip("验证码已经发送到邮箱，注意查收！", true);
        qDebug() << "email is " << email << "\n";
        return;
    });
    // 重置密码请求
    _handlers.insert(ReqId::ID_RESET_PWD, [this](const QJsonObject &jsonObject) {
        int error = jsonObject["error"].toInt();
        if (error != ErrorCode::SUCCESS) {
            qDebug() << "error is " << error;
            showTip("重置密码错误");
            return;
        }
        QString email = jsonObject["email"].toString();
        QString uuid = jsonObject["uuid"].toString();
        showTip("重置密码成功，点击返回登录。", true);
        qDebug() << "email is " << email;
        qDebug() << "user uuid is " << uuid;
        return;
    });
}

void ForgetDialog::on_forget_btn_ok_clicked()
{
    QString user = ui->forget_edt_user->text();
    if (user.isEmpty()) {
        showTip("用户名不能为空");
        return;
    }
    QString email = ui->forget_edt_email->text();
    if (email.isEmpty()) {
        showTip("邮箱不能为空");
        return;
    }
    QString verifyCode = ui->forget_edt_verify->text();
    if (verifyCode.isEmpty()) {
        showTip("验证码不能为空");
        return;
    }
    QString pwd = ui->forget_edt_password->text();
    if (pwd.isEmpty()) {
        showTip("密码不能为空");
        return;
    }
    QString encryptedPwd = QCryptographicHash::hash(pwd.toUtf8(), QCryptographicHash::Sha1).toHex();
    QJsonObject root;
    root["user"] = user;
    root["email"] = email;
    root["password"] = encryptedPwd;
    root["verifyCode"] = verifyCode;
    // 发送重置密码请求
    HttpManager::GetInstance()->PostHttpReq(QUrl(gate_url_prefix + "/reset_pwd"),
                                            root,
                                            ReqId::ID_RESET_PWD,
                                            Modules::RESETPWDMOD);
}

void ForgetDialog::on_forget_btn_back_clicked()
{
    _timer.stop();
    emit sigSwitchLogin();
}
